﻿@page "/GridRemoteDataSource"
@using DevExtreme.AspNet.Data.ResponseModel
@using DevExtreme.AspNet.Data
@using System.Threading
@using System.Threading.Tasks
@using System.Net.Http
@using System.Text.Json

<div class="demo-description mw-1100" id="CustomDataSource">
    <h2><DemoNavLink Link="GridRemoteDataSource#CustomDataSource" />Data Grid - Custom Data Source</h2>
    <p>
        This demo illustrates how to bind the <a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1" target="_blank">Data Grid</a> component to a Web API service.
        To do this, assign the data source type to the component’s <b>T</b> parameter and use the <a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1.CustomData" target="_blank">CustomData</a> property to implement data load logic.
        Use the <b>ConvertToGetRequestUri</b> extension method to generate a GET request URI with parameters based on load options (a <a class="helplink" href="https://devexpress.github.io/DevExtreme.AspNet.Data/net/api/DevExtreme.AspNet.Data.DataSourceLoadOptionsBase.html" target="_blank">DataSourceLoadOptionsBase</a> object).
    </p>

    <p>
        In this demo, the <b>Customer ID</b> and <b>Ship Via</b> columns are bound to the Web API service via the <a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGridComboBoxColumn-1.CustomData" target="_blank">CustomData</a> property.
    </p>
</div>

<DxDataGrid T="@WebApiOrder" CustomData="@LoadOrderData" ShowFilterRow="true" CssClass="mw-1100">
    <Columns>
        <DxDataGridComboBoxColumn T="@(WebApiCustomerLookup)" TextFieldName="Text" ValueFieldName="Value"
                                  CustomData="@LoadCustomerData" Field="@nameof(WebApiOrder.CustomerID)" Width="300px" />
        <DxDataGridDateEditColumn Field="@nameof(WebApiOrder.OrderDate)" Width="180px" />
        <DxDataGridSpinEditColumn Field="@nameof(WebApiOrder.Freight)" DisplayFormat="c" Width="180px" />
        <DxDataGridColumn Field="@nameof(WebApiOrder.ShipCountry)" Width="210px" />
        <DxDataGridComboBoxColumn T="@(WebApiShipperLookup)" TextFieldName="Text" ValueFieldName="Value"
                                  CustomData="@LoadShipmentData" Field="@nameof(WebApiOrder.ShipVia)" Width="220px" />
    </Columns>
</DxDataGrid>
<CodeSnippet_Grid_DataBinding_CustomDataSource />
@code {
    [Inject] protected HttpClient Client { get; set; }

    protected async Task<LoadResult> LoadOrderData(DataSourceLoadOptionsBase options, CancellationToken ct)
        => await LoadCustomData("https://js.devexpress.com/Demos/NetCore/api/DataGridWebApi/Orders", options, ct);
    protected async Task<LoadResult> LoadCustomerData(DataSourceLoadOptionsBase options, CancellationToken ct)
        => await LoadCustomData("https://js.devexpress.com/Demos/NetCore/api/DataGridWebApi/CustomersLookup", options, ct);
    protected async Task<LoadResult> LoadShipmentData(DataSourceLoadOptionsBase options, CancellationToken ct)
        => await LoadCustomData("https://js.devexpress.com/Demos/NetCore/api/DataGridWebApi/ShippersLookup", options, ct);

    protected async Task<LoadResult> LoadCustomData(string dataEndpointUri, DataSourceLoadOptionsBase options, CancellationToken ct)
    {
        using var response = await Client.GetAsync(options.ConvertToGetRequestUri(dataEndpointUri));
        response.EnsureSuccessStatusCode();
        using var responseStream = await response.Content.ReadAsStreamAsync();
        return await JsonSerializer.DeserializeAsync<LoadResult>(responseStream);
    }
}

<div class="demo-description mw-1100" id="AsyncOperations">
    <h2><DemoNavLink Link="GridRemoteDataSource#AsyncOperations" />Data Grid - Asynchronous Data-Aware Operations</h2>
    <p>
        This demo illustrates how the <a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1" target="_blank">Data Grid</a> component performs data-aware operations asynchronously:
        removes/adds/updates rows, sorts/filters data, navigates between pages, and so on.
        These operations do not disable the Data Grid’s user interface during execution.
    </p>
    <p>The Data Grid ships with the following asynchronous API members:</p>
    <ul>
        <li>
            <p><a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1.DataAsync" target="_blank">DataAsync</a> – Specifies an asynchronous function that returns the data source.</p>
        </li>
        <li>
            <p><a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1.RowRemovingAsync" target="_blank">RowRemovingAsync</a> - Fires when a user deletes a data row.</p>
        </li>
        <li>
            <p><a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1.RowUpdatingAsync" target="_blank">RowUpdatingAsync</a> - Fires when a user edits a data row.</p>
        </li>
        <li>
            <p><a class="helplink" href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxDataGrid-1.RowInsertingAsync" target="_blank">RowInsertingAsync</a> - Fires when a user adds a data row.</p>
        </li>
    </ul>
</div>

<DxDataGrid DataAsync="@ForecastService.GetForecastAsync"
            PageSize="5"
            RowRemovingAsync="@OnRowRemoving"
            RowUpdatingAsync="@OnRowUpdating"
            RowInsertingAsync="@OnRowInserting"
            CssClass="mw-1100">
    <DxDataGridCommandColumn Width="150px" />
    <DxDataGridDateEditColumn Field="@nameof(WeatherForecast.Date)" DisplayFormat="D" EditorFormat="D" />
    <DxDataGridColumn Field="@nameof(WeatherForecast.Forecast)" Caption="Forecast" Width="150px" />
    <DxDataGridSpinEditColumn Field="@nameof(WeatherForecast.TemperatureC)" Caption="@("Temp. (\x2103)")" TextAlignment="DataGridTextAlign.Left" Width="150px" />
    <DxDataGridComboBoxColumn Field="@nameof(WeatherForecast.CloudCover)" Caption="Cloud Cover" DataAsync="@ForecastService.GetCloudCoverAsync" TextAlignment="DataGridTextAlign.Left" Width="150px" />
    <DxDataGridCheckBoxColumn Field="@nameof(WeatherForecast.Precipitation)" Caption="Precipitation" Width="100px" />
</DxDataGrid>
<CodeSnippet_Grid_DataBinding_AsyncSupport />

@code {

    [Inject] protected WeatherForecastService ForecastService { get; set; }
    [Inject] protected IJSRuntime JSRuntime { get; set; }

    async Task OnRowRemoving(WeatherForecast dataItem) {
        bool approved = await JSRuntime.InvokeAsync<bool>("confirm", "Are you sure you want to delete this record?");
        if (approved)
            await ForecastService.Remove(dataItem);
    }
    async Task OnRowUpdating(WeatherForecast dataItem, IDictionary<string, object> newValue) {
        await Task.Delay(2000);
        await ForecastService.Update(dataItem, newValue);
    }
    async Task OnRowInserting(IDictionary<string, object> newValue) {
        await Task.Delay(2000);
        await ForecastService.Insert(newValue);
    }
}
